#include "vector.h"
#include <stdlib.h>

Vector::Vector(const unsigned int _row): row(_row) {
    data = new double[row];

    for(unsigned int i = 0; i < row; i++)
        data[i] = 0;
}

Vector::Vector(const Vector& _v) {
    row = _v.getRow();
    data = new double[row];

    for(unsigned int i = 0; i < row; i++)
        data[i] = _v[i];
}

Vector::~Vector() {
    delete[] data;
}

double Vector::innerProduct(const Vector & _vector) const {
    double result = 0.0;

    for(unsigned int i = 0; i < row; i++)
        result += data[i] * _vector[i];
    
    return result;
}

Matrix Vector::outterProduct(const Vector & _vector) const {
    Matrix result(row,_vector.getRow());

    for(unsigned int i = 0; i < row; i++) {
        for(unsigned int j = 0; j < _vector.getRow(); j++) {
            result[i][j] = data[i] * _vector[j];
        }
    }

    return result;
}

Vector Vector::scalarProduct(const double & _scalar) const {
    Vector result(row);

    for(unsigned int i = 0; i < row; i++) {
        result[i] = data[i]*_scalar;
    }

    return result;
}

double Vector::length(void) const {
    return sqrt(this->innerProduct((*this)));
}

Vector Vector::normalize(void) const {
    double l = this->length();
    if(l != 0) {
        return this->scalarProduct( 1.0/l );
    } else {
        return Vector(row);
    }
}

unsigned int Vector::getRow(void) const {
    return row;
}

void Vector::print(void) {
    for(unsigned int i = 0; i < row; i++)
        std::cout << "|\t" << data[i] << "\t|" << std::endl;
}

Matrix Vector::toMatrixColumn(void) const {
    Matrix result(row, 1);

    for(unsigned int i = 0; i < row; i++) {
        result[i][0] = data[i];
    }

    return result;
}

double& Vector::operator[](unsigned int i) const {
    if(i >= row)
        exit(1);
    
    return data[i];
}

Vector Vector::operator-() {
    return this->scalarProduct(-1);
}

Vector& Vector::operator=(const Vector& _v1) {
    delete[] data;
    
    row = _v1.getRow();
    data = new double[row];

    for(unsigned int i = 0; i < row; i++)
        data[i] = _v1[i];

    return *this;
}

Vector operator+(const Vector& _v1, const Vector& _v2) {
    if(_v1.getRow() != _v2.getRow())
        exit(1);
    
    unsigned int nrow = _v1.getRow();

    Vector result(nrow);

    for(unsigned int i = 0; i < nrow; i++)
        result[i] = _v1[i] + _v2[i];

    return result;
}

Vector operator-(const Vector& _v1, const Vector& _v2) {
    if(_v1.getRow() != _v2.getRow())
        exit(1);
    
    unsigned int nrow = _v1.getRow();

    Vector result(nrow);

    for(unsigned int i = 0; i < nrow; i++)
        result[i] = _v1[i] - _v2[i];

    return result;
}

